home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / comm.com / COMM.H < prev   
Encoding:
C/C++ Source or Header  |  1988-09-21  |  8.6 KB  |  314 lines

  1. /******************************************************/
  2. /*  COMM.H  - this set of routines creates a          */
  3. /*            interupt driven communications          */
  4. /*            interface for MSC 5.0 & quickC.         */
  5. /*            By  Mario Giannini                      */
  6. /*                                                    */
  7. /*                                                    */
  8. /*  setintr(port) - install driver for com port       */
  9. /*              port where 0 = com1:                  */
  10. /*              returns -1 if port not installed      */
  11. /*                                                    */
  12. /*  resetint(port) - remove above driver              */
  13. /*                                                    */
  14. /*  seravl() -  tests to see if a character is        */
  15. /*              available in the serial buffer        */
  16. /*                                                    */
  17. /*  getser() -  gets a character from the serial      */
  18. /*              buffer                                */
  19. /*                                                    */
  20. /*  portinit(port, baud, parity, data, stop)          */
  21. /*              returns  0 if ok                      */
  22. /*                      -1 if port not there,         */
  23. /*                      -2 if invalid parameter       */
  24. /*                                                    */
  25. /*  is_carrier(port) - returns a non-zero if          */
  26. /*                     carrier detect is true         */
  27. /*                                                    */
  28. /*                                                    */
  29. /*  sendstr(str) - transmits a string to port,        */
  30. /*                 translates a '|' into CR, and      */
  31. /*                                                    */
  32. /*  xmit(ch) -  transmit character ch                 */
  33. /*                                                    */
  34. /*  clr_buf() - clears out buffer                     */
  35. /*                                                    */
  36. /*  onesec() - one second time delay                  */
  37. /*                                                    */
  38. /*  hwhangup() - hangup modem through DTR line        */
  39. /*               gets port from variable init'ed by   */
  40. /*               portinit                             */
  41. /******************************************************/
  42.  
  43. #ifndef BUFSIZE
  44.    #define BUFSIZE  8192
  45. #endif
  46. #define MAXPORTS 2
  47. #define seravl() (tailp!=headp)
  48. #define keyavl() kbhit()
  49.  
  50. int _int_port;  /* 1 for COM1, 2 for COM2, etc...  */
  51.  
  52. /****************************************/
  53. /*  serial interupt data & declarations */
  54. /****************************************/
  55.  
  56.  
  57. struct comport {
  58.        int inport[MAXPORTS];      /* input port address of UART  */
  59.        int outport[MAXPORTS];     /* output port  ""             */
  60.        int baudl[MAXPORTS];       /* baud rate divisor high and low bytes */
  61.        int baudh[MAXPORTS];
  62.        int inten[MAXPORTS];       /* interupt enable port  */
  63.        int intid[MAXPORTS];       /* interupt id port  */
  64.        int lcreg[MAXPORTS];       /* line control register */
  65.        int mcreg[MAXPORTS];       /* modem control reg */
  66.        int lstatus[MAXPORTS];     /*  line status reg  */
  67.        int mstatus[MAXPORTS];     /*  modem status reg  */
  68.        int intmsk[MAXPORTS];     /*  mask for com port interupt  */
  69.        int intr[MAXPORTS];
  70.        } comx = {
  71.                 {0x3f8, 0x2f8},
  72.                 {0x3f8, 0x2f8},
  73.                 {0x3f8, 0x2f8},
  74.                 {0x3f9, 0x2f9},
  75.                 {0x3f9, 0x2f9},
  76.                 {0x3fa, 0x2fa},
  77.                 {0x3fb, 0x2fb},
  78.                 {0x3fc, 0x2fc},
  79.                 {0x3fd, 0x2fd},
  80.                 {0x3fe, 0x2fe},
  81.                 {0xef,  0xf7},
  82.                 {0x0c,  0x0b}
  83.                 };
  84.                 /* column 1 is com1, column 2 is com2, etc.. */
  85.  
  86.  
  87. volatile char _icbuffer[BUFSIZE];    /* buffer storage, head & tails pointers */
  88. volatile char *headp, *tailp, *buf_end, *buf_beg;
  89.  
  90. void (_CDECL interrupt far *serial)();  /* for origninal serial int. */
  91.  
  92. void _CDECL interrupt far handler(void);
  93.  
  94. /****************************************/
  95. /*  The actual serial interface driver  */
  96. /****************************************/
  97.  
  98. void _CDECL interrupt far handler()
  99. {
  100. int dummy;   /* this is to allow for a bug in MSC 5.0 that may
  101.                 delete code when optimizing  */
  102. _disable();
  103.  
  104. *tailp++=inp(comx.inport[_int_port]);
  105. if (tailp==buf_end)
  106.    tailp=buf_beg;
  107. if (tailp==headp) {
  108.    headp++;
  109.    if (headp==buf_end)
  110.       headp=buf_beg;
  111.    }
  112. _enable();
  113. outp(0x20, 0x20);   /* send an end of interupt signal to hardare */
  114.  
  115. _chain_intr(serial);
  116. }
  117. /******END OF SERIAL INTERUPT***************/
  118.  
  119.  
  120. /*****************************************/
  121. /*     SET & RESET SERIAL INTERUPT       */
  122. /*****************************************/
  123.  
  124. setintr(int cport)
  125. {
  126. unsigned i;
  127. buf_beg=_icbuffer;
  128. buf_end=&_icbuffer[BUFSIZE];
  129. tailp=buf_beg;
  130. headp= buf_beg;
  131. if (inp(comx.inport[cport])==0xFF && inp(comx.lstatus[cport])==0xFF && inp(comx.lcreg[cport])==0xFF)
  132.    return(-1);   /* no UART found at port address */
  133.  
  134.      /* install the handler  */
  135. _int_port=cport;
  136. serial=_dos_getvect(comx.intr[cport]);
  137. _dos_setvect(comx.intr[cport], handler);    /* point to our handler  */
  138.  
  139.              /*  set up the interupt controller  */
  140.  
  141. outp(comx.mcreg[cport], 0xB);   /* set OUT2, DTR, & RTS on UART  */
  142. outp(comx.inten[cport], 1);     /* set interupt enable reg on UART to data ready */
  143. i=inp(0x21);                  /* setup interupt controller chip  */
  144. i= (i & comx.intmsk[cport]);
  145. outp(0x21, i);
  146. return(0);
  147. }
  148.  
  149.  
  150. resetintr(int cport)
  151. {
  152. int i,j;
  153. /* first disable the interupts via interrupt mask on PIC chip */
  154.  
  155. i=~comx.intmsk[cport];
  156. j=inp(0x21);
  157. j=j | i;
  158. /* outp(0x21, j); */
  159.  
  160. /*  then restore the original serial intr pointer  */
  161.  
  162. _dos_setvect(comx.intr[cport], serial);
  163. }
  164.  
  165. /*******************************************/
  166. /*         recieve to COM? functions       */
  167. /*******************************************/
  168.  
  169. getser()
  170. {
  171. int ch;
  172.  
  173. ch=*headp++;
  174. if (headp==buf_end)
  175.    headp=buf_beg;
  176. return(ch);
  177. }
  178.  
  179.  
  180. /******************************************/
  181. /* func to init COM? to correct settings  */
  182. /* returns a -1 if port not there,        */
  183. /*           -2 if invalid parameter      */
  184. /*            0 if ok                     */
  185. /******************************************/
  186.  
  187. portinit(cport, baud, parity, data, stop)
  188. int cport, baud, parity, data, stop;
  189. {
  190.  
  191. unsigned char attrib=0;
  192. char temp;
  193. int cbaud;
  194.  
  195.  
  196. /* these items setup the attribute bits for the byte to be sent
  197.    to the UART (data bits, stop bits, etc.)  */
  198.  
  199. if (inp(comx.inport[cport])==0xFF && inp(comx.lstatus[cport])==0xFF && inp(comx.lcreg[cport])==0xFF)
  200.    return(-1);   /* no UART found at port address */
  201.  
  202.  
  203. if (cport>MAXPORTS || parity>2 || data>8 || stop>2)
  204.    return(-2);
  205. if (parity != 0) {
  206.    if (parity==1)
  207.       attrib=8;
  208.    else
  209.       attrib=24;
  210.    }
  211. if (stop>1)
  212.    attrib=attrib+4;
  213. temp=data-5;
  214. attrib=attrib+temp;
  215. cbaud=0;
  216. if (baud==9600)
  217.    cbaud=0xC;
  218. else
  219.    if (baud==4800)
  220.       cbaud=0x18;
  221.    else
  222.       if (baud==2400)
  223.          cbaud=0x30;
  224.       else
  225.          if (baud==1200)
  226.             cbaud=0x60;
  227.          else
  228.             if (baud==300)
  229.                cbaud=0x180;
  230.             else
  231.                return(-2);
  232.  
  233. outp(comx.lcreg[cport], (unsigned) 0x80);
  234. outp(comx.baudl[cport], cbaud%0x100);
  235. outp(comx.baudh[cport], cbaud/0x100);
  236. outp(comx.lcreg[cport], attrib);
  237.  
  238. return(0);
  239.  
  240. }
  241.  
  242. is_carrier(int cport)
  243. {
  244. int i;
  245. i=inp(comx.mstatus[cport]);
  246. #ifdef DEBUG
  247.   return(0x80);
  248. #else
  249.   return(i&0x80);
  250. #endif
  251. }
  252.  
  253. clr_buf()       /* clear communications buffer */
  254. {
  255. tailp=buf_beg;
  256. headp=tailp;
  257. }
  258.  
  259.  
  260. xmit(char ch)
  261. {
  262. #ifdef DEBUG
  263.   putch(ch);
  264. #else
  265.   while ( ((inp(comx.lstatus[_int_port])) & 0x20 ) ==0);
  266.   outp(comx.outport[_int_port], ch);
  267. #endif
  268. }
  269.  
  270. sendstr(char *str)
  271. {
  272. while (*str)  {
  273.    if (*str == '|')
  274.       xmit(13);
  275.    else if (*str=='~')  {
  276.       onesec();
  277.       }
  278.    else
  279.       xmit(*str);
  280.    str++;
  281.    }
  282.  
  283. }
  284.  
  285. onesec()
  286. {
  287. union REGS regin, regout;
  288.  
  289. unsigned int dest;
  290.  
  291. regin.h.ah=0;
  292. int86(0x1A, ®in, ®out);
  293. dest=regout.x.dx+18;
  294. while( (unsigned) regout.x.dx < dest) {
  295.    regin.h.ah=0;
  296.    int86( 0x1A, ®in, ®out);
  297.    }
  298. }
  299.  
  300. hwhangup()
  301. {
  302. int i;
  303. i=inp(comx.mcreg[_int_port]);
  304. i=i&0xFE;
  305. outp(comx.mcreg[_int_port], 0);  /* all bits off, then on, then normal */
  306. inp(comx.mcreg[_int_port]);
  307. outp(comx.mcreg[_int_port], 0xFF);
  308. inp(comx.mcreg[_int_port]);
  309. outp(comx.mcreg[_int_port], i);
  310. onesec();
  311. i=i|1;
  312. outp(comx.mcreg[_int_port], i);
  313. }
  314.